package com.lock.redisLock;

import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * 订单Redis锁
 */
public class RSOLockUtil implements Closeable {

    Logger log = LoggerFactory.getLogger(this.getClass());

    Map<String, Boolean> prodCodeLockMaps = Maps.newTreeMap(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }
    });

    private boolean success = false;

    private String lockPrefix = "stock_lock_prod_code_";

    //单位秒
    private int lockExpireTime = 10 * 60;

    //单位毫秒
    private int lockWaitTiem = 5 * 1000;

    private RedisBatchLock redisBatchLock;

    public RSOLockUtil() {
        redisBatchLock = new RedisBatchLock();
    }

    public static RSOLockUtil create() {
        return new RSOLockUtil();
    }

    public RSOLockUtil setProdCode(String... prodCodes) {
        for (String prodCode : prodCodes) {
            prodCodeLockMaps.put(prodCode, false);
        }
        return this;
    }

    public RSOLockUtil lock() {
        List<String> prodCodes = redisBatchLock.batchLock(lockPrefix, new ArrayList(prodCodeLockMaps.keySet()), lockExpireTime);

        if (prodCodes.size() != prodCodeLockMaps.size()) {
            this.success = false;
            return this;
        }

        this.success = true;
        return this;
    }

    public void unlock() {
        redisBatchLock.unlock();

        log.info("rso unlock is success!");
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public Map<String, Boolean> getProdCodeLockMaps() {
        return prodCodeLockMaps;
    }

    public void setProdCodeLockMaps(Map<String, Boolean> prodCodeLockMaps) {
        this.prodCodeLockMaps = prodCodeLockMaps;
    }

    public String getLockPrefix() {
        return lockPrefix;
    }

    public void setLockPrefix(String lockPrefix) {
        this.lockPrefix = lockPrefix;
    }

    public int getLockExpireTime() {
        return lockExpireTime;
    }

    public void setLockExpireTime(int lockExpireTime) {
        this.lockExpireTime = lockExpireTime;
    }

    public int getLockWaitTiem() {
        return lockWaitTiem;
    }

    public void setLockWaitTiem(int lockWaitTiem) {
        this.lockWaitTiem = lockWaitTiem;
    }

    @Override
    public void close() throws IOException {
        this.unlock();
    }

}